package com.zytech.zspider.task.impl;

import com.zytech.modules.lang.Ghost;
import com.zytech.zspider.core.TaskDefinition;
import com.zytech.zspider.core.TaskException;
import com.zytech.zspider.core.TaskResult;
import com.zytech.zspider.core.TaskResultPipelineSettings;
import com.zytech.zspider.task.*;

import java.util.Map;

/**
 * @author siuming
 */
public final class TaskResultResetHandler implements TaskResultHandler {

    @Override
    public TaskResult onResult(TaskExecutor executor,
                               TaskDefinition task,
                               TaskContext context,
                               TaskResult result) {

        TaskResultPipelineSettings settings = task.getPipelineSettings();
        if (null == settings || !settings.isRequiresProcess()) {
            return result;
        }

        try {
            context.putBinding(TaskContext.TASK_RESULT, result);

            Object newValue = executor.getExpressionEvaluator().eval(settings.getProcess(), context);
            Ghost<?> ghost = Ghost.me(newValue);
            if (ghost.openEyes().isOf(TaskResult.class)) {
                return (TaskResult) newValue;
            }

            if (!ghost.openEyes().isMap()) {
                throw new TaskException("Unknown reset resultType. it must be TaskResult or Map<String,Object>.");
            }

            Map<String, Object> asMap = (Map<String, Object>) newValue;
            return TaskResult
                    .ofBuilder()
                    .taskname(result.getTaskname())
                    .startTime(result.getStartTime())
                    .elapsedTime(result.getElapsedTime())
                    .values(asMap)
                    .build();
        } finally {
            context.putBinding(TaskContext.TASK_RESULT, TaskResult.EMPTY);
        }

    }
}
